<template>
    <!-- 左侧导航栏 -->
    <div class="left-nav">
        <div><slot></slot></div>
        <div class="nav-title">
            <span class="nav-text">分组管理</span>
            <el-tooltip content="添加分组" effect="dark" placement="top">
                <el-icon color="#FF6B00" class="plus-icon" @click="addGroup(false, firstId, 'add')"><plus /></el-icon>
            </el-tooltip>
        </div>
        <div class="groups block">
            <el-input v-model="filterText" class="search_group" placeholder="请输入分组名称" />
            <el-scrollbar wrap-class="tree-scrollbar" :height="treeHeight">
                <el-tree
                    ref="treeRef"
                    class="filter-tree"
                    :filter-node-method="filterNode"
                    check-on-click-node
                    node-key="id"
                    :default-expand-all="true"
                    :props="defaultProps"
                    :data="groupData"
                    @node-click="nodeClick">
                    <template #default="{ node, data }">
                        <template v-if="['all', 0].includes(data.id)">
                            <div
                                v-if="data.id == 'all'"
                                :class="data.pid ? 'hover-text hide' : 'hover-text'"
                                @mouseover="mouseOver(data)"
                                @mouseleave="mouseLeave(data)">
                                <div :class="selectId == data.id ? 'hover-detail-color' : 'hover-detail'">
                                    {{ `${data.name}（${data.nums ?? data.count}）` }}
                                </div>
                                <el-tooltip
                                    placement="right"
                                    effect="light"
                                    :hide-after="0"
                                    :offset="0"
                                    @show="mouseOver2(data)"
                                    @hide="mouseLeave2(data)">
                                    <template #content>
                                        <div class="tooltip-link">
                                            <el-link
                                                v-auth="props.authCode.add"
                                                class="link-text"
                                                :underline="false"
                                                type="primary"
                                                @click="addGroup(false, data, 'add')">
                                                添加子分组
                                            </el-link>
                                        </div>
                                    </template>
                                    <span class="icon-span">
                                        <el-icon color="#FF6B00" class="hover-icon">
                                            <more-filled />
                                        </el-icon>
                                    </span>
                                </el-tooltip>
                            </div>

                            <div
                                v-else
                                :class="data.pid ? 'hover-text hide' : 'hover-text'"
                                @mouseover="mouseOver(data)"
                                @mouseleave="mouseLeave(data)">
                                <div :class="selectId == data.id ? 'hover-detail-color' : 'hover-detail'">
                                    {{ `${data.name}（${data.nums ?? data.count}）` }}
                                </div>
                            </div>
                        </template>
                        <div
                            v-else
                            :class="data.pid ? 'hover-text hide' : 'hover-text'"
                            @mouseover="mouseOver(data)"
                            @mouseleave="mouseLeave(data)">
                            <div :class="selectId == data.id ? 'hover-detail-color' : 'hover-detail'">
                                {{ `${data.name}（${data.nums ?? data.count}）` }}
                            </div>

                            <el-tooltip
                                placement="right"
                                effect="light"
                                :hide-after="0"
                                :offset="0"
                                @show="mouseOver2(data)"
                                @hide="mouseLeave2(data)">
                                <template #content>
                                    <div class="tooltip-link">
                                        <el-link
                                            v-if="node.level <= 2"
                                            v-auth="props.authCode.add"
                                            class="link-text"
                                            :underline="false"
                                            type="primary"
                                            @click="addGroup(false, data, 'add')">
                                            添加子分组
                                        </el-link>
                                        <el-link
                                            v-auth="props.authCode.edit"
                                            class="link-text"
                                            :underline="false"
                                            type="primary"
                                            @click="addGroup(true, data)">
                                            编辑
                                        </el-link>
                                        <el-link
                                            v-auth="props.authCode.del"
                                            class="link-text"
                                            :underline="false"
                                            type="primary"
                                            @click="removeGroup(data)">
                                            删除
                                        </el-link>
                                    </div>
                                </template>
                                <span class="icon-span">
                                    <el-icon color="#FF6B00" class="hover-icon"><more-filled /></el-icon>
                                </span>
                            </el-tooltip>
                        </div>
                    </template>
                </el-tree>
            </el-scrollbar>
        </div>
    </div>
    <!-- 添加分组 -->
    <Dialog :app-dialog="appDialog">
        <el-form
            ref="ruleFormRef"
            :model="addGroupingForm"
            :rules="rules"
            label-width="100px"
            class="demo-ruleForm"
            :size="formSize">
            <el-form-item label="选择分组" prop="selectGroup">
                <el-cascader
                    ref="cascaderRef"
                    v-model="addGroupingForm.selectGroup"
                    class="formInput"
                    :disabled="firstlevel || isUpdate"
                    :options="isUpdate || add ? EditGroupData : groupData"
                    :props="defaultProps"
                    placeholder="请选择分组"
                    filterable
                    popper-class="casader_pop"
                    @change="orgChange" />
            </el-form-item>
            <el-form-item label="分组名称" prop="name">
                <el-input
                    v-model="addGroupingForm.name"
                    class="formInput"
                    placeholder="请输入分组名称"
                    maxlength="12"
                    show-word-limit
                    clearable></el-input>
            </el-form-item>
        </el-form>
    </Dialog>
    <!-- 删除弹框 -->
    <ZWDeletdialog ref="groupDialogRef" @submit="delBtn" />
</template>

<script setup lang="ts">
import { ref, watch, reactive, onMounted, computed, nextTick } from 'vue';
import { ElMessage, ElTree, ElForm } from 'element-plus';
import Dialog from '@/components/Dialog.vue';
import ZWDeletdialog from '@/components/ZWDeletdialog.vue';
import { creatGroup, updateGroup, delGroup, getGroupList } from '@/api/concreation';
import { useStore } from '@/store';
import { startLoading, endLoading } from '@/utils/request';
import { treeH, reSize } from '@/utils/utils';

const store = useStore();
const ruleFormRef = ref();
const treeRef = ref<InstanceType<typeof ElTree>>();
const cascaderRef: any = ref(null); // 选择分组ref
const emit = defineEmits(['submit']);

// 权限code码
interface AuthCode {
    add: string; // 添加子分组
    edit: string; // 编辑
    del: string; // 删除
}
const props = withDefaults(
    defineProps<{
        groupId?: number | string; // 默认选中分组Id
        type: number | string; // 页面类型
        authCode: AuthCode; // 权限code码
        getGroupFun?: () => void; // 自定义获取分组列表api方法
        gap: number; // 差值
    }>(),
    {
        type: 1,
        authCode: () => ({
            add: 'ADD_SUBGROUP',
            edit: 'EDIT_SUBGROUP',
            del: 'DEL_SUBGROUP'
        }),
        groupId: 0,
        gap: 274
    }
);
// 分组 tree
const groupData = ref<Array<any>>([]);
const groupDialogRef = ref();
interface Tree {
    id: number;
    name: string;
    children?: Tree[];
}
// 添加分组表单
const addGroupingForm = reactive({
    selectGroup: 0, // 选择分组
    name: '' // 添加分组名称
});
// 添加分组校验规则
const rules = reactive({
    name: [
        {
            required: true,
            message: '请填写分组名称',
            trigger: 'blur'
        }
    ]
});
const EditGroupData = ref<any[]>([]);
const selectId = ref(store.getters.group_id || 0);
const filterText = ref(''); // 搜索分组
const isUpdate = ref(false); //是否是编辑弹框
const add = ref(false); // 添加
const firstlevel = ref(false); // 添加
const firstId = ref({});
// 1-文本 2-图片 3-音频 4-视频 5-文件 6-链接文章 7-链接引用 8-朋友圈素材
// eslint-disable-next-line
const type = ref(1);
const treeHeight = ref<string>('660px');
// 取消按钮
const cancelHandel = () => {
    appDialog.visible = false;
    isUpdate.value = false;
    ruleFormRef.value.resetFields();
};
/** 当前操作的id，点击了添加子分组/编辑/删除之后的分组id,并非当前选中的id */
let currentData: { id: number | 'all'; pid: number | 'all'; children?: any[] } = {
    id: 'all',
    pid: 'all'
};

// 保存按钮
const submitHandel = async () => {
    await ruleFormRef.value.validate();
    try {
        const params = {
            type: type.value,
            name: addGroupingForm.name,
            group_id: currentData.id == 'all' ? 0 : currentData.id,
            pid: addGroupingForm.selectGroup == 'all' ? 0 : addGroupingForm.selectGroup
        };
        startLoading();
        isUpdate.value ? await updateGroup(params) : await creatGroup(params);
        ElMessage.success(`${isUpdate.value ? '更新' : '创建'}分组成功`);
        await getGroup(0, 'submitHandle');
        cancelHandel();
    } catch (error) {
        endLoading();
    }
};
// 弹框相关配置
const appDialog = reactive({
    visible: false,
    title: `创建分组`,
    width: '500px',
    cancel: cancelHandel,
    submit: submitHandel,
    cancelText: '取消',
    submitText: '保存'
});

const defaultProps = {
    checkStrictly: true,
    emitPath: false,
    label: 'name',
    value: 'id'
};

watch(filterText, val => {
    treeRef.value!.filter(val);
});
// 搜索分组
const filterNode = (value: string, data: Tree) => {
    if (!value) return true;
    return data.name.indexOf(value) !== -1;
};

//鼠标移入
const mouseOver = (data: any) => {
    data.showEdit = true;
};
//鼠标移出
const mouseLeave = (data: any) => {
    data.showEdit = false;
};

//鼠标移入 tooltip
const mouseOver2 = (data: any) => {
    const ele = getElementByAttr('div', 'data-key', data.id);
    ele[0].getElementsByClassName('el-tree-node__content')[0].classList.add('tree-hover');
};
//鼠标移出 tooltip
const mouseLeave2 = (data: any) => {
    const ele = getElementByAttr('div', 'data-key', data.id);
    ele[0].getElementsByClassName('el-tree-node__content')[0].classList.remove('tree-hover');
};
// 根据data-key属性获取dom
const getElementByAttr = (tag: any, attr: any, value: any) => {
    const aElements = document.getElementsByTagName(tag);
    const aEle = [];
    for (let i = 0; i < aElements.length; i++) {
        if (aElements[i].getAttribute(attr) == value) aEle.push(aElements[i]);
    }
    return aEle;
};

//切换id
const changeGroup = (data: any) => {
    selectId.value = data.id;
    emit('submit', data);
    store.dispatch('setGroupId', data.id);
};
// 选择完地区后立即关闭
const orgChange = () => {
    cascaderRef.value.togglePopperVisible();
};

// 新增/编辑分组的弹框
const addGroup = (flag: boolean, data?: any, type?: string) => {
    if (type == 'add') add.value = true;
    else add.value = false;
    if (data.pid == 0 && flag) firstlevel.value = true;
    else firstlevel.value = false;
    isUpdate.value = flag;
    appDialog.title = `${flag ? '更新' : '创建'}分组`;
    currentData = data;
    addGroupingForm.selectGroup = flag ? (data.pid == 0 ? 'all' : data.pid) : data.id;
    addGroupingForm.name = flag ? data.name : '';
    appDialog.visible = true;
};
// 删除
const removeGroup = (data: any) => {
    currentData = data;
    groupDialogRef.value.content =
        '删除该分组后，数据将会迁移至其父分组，若没有父分组，数据将会迁移至默认分组。确定要删除该分组吗？';
    groupDialogRef.value.appDialog.visible = true;
};
// 删除分组确认按钮
const delBtn = () => {
    startLoading();
    delGroup({
        group_id: currentData.id
    })
        .then(async (res: any) => {
            groupDialogRef.value.appDialog.visible = false;
            ElMessage.success(`删除分组成功`);
            // 如果是删除了当前选中的分组，则默认到父分组，如果没有父分组，则到默认分组
            // 或者是，删除的是当前选中的父分组
            if (
                Number(selectId.value) === currentData.id ||
                currentData?.children?.find(item => item.id === selectId.value)
            ) {
                selectId.value = currentData.pid || 0;
                emit('submit', { id: currentData.pid });
            }
            await getGroup(0, 'delBtn');
        })
        .catch(() => {
            endLoading();
        });
};
// 获取分组列表详情
const getGroup = async (num?: number, handleType?: string) => {
    startLoading();
    const params = {
        type: num && num !== 0 ? num : type.value
    };
    try {
        const res: any = await (props.getGroupFun ? props.getGroupFun(params) : getGroupList(params));
        const result: any[] = [
            {
                name: '全部分组',
                id: 'all',
                nums: 0,
                children: []
            }
        ];
        if (res.data.length > 0) {
            const normal = res.data.find((item: any) => item.id === 0);
            normal.disabled = true;
            result[0].nums = res.total;
            result[0].children = res.data;
        }
        firstId.value = {
            name: '全部分组',
            id: 'all'
        };
        groupData.value = result;
        const child = JSON.parse(JSON.stringify(res.data));
        if (child.length > 0) {
            child.forEach((item: any) => {
                delete item.children;
            });
        }
        EditGroupData.value = [
            {
                name: '全部分组',
                id: 'all',
                nums: 0,
                children: child
            }
        ];
        store.dispatch('content/group', {
            groupId: selectId.value,
            groupList: res.data
        });
    } catch (error) {
    } finally {
        handleType && endLoading();
    }
};
const nodeClick = (val: any, node: any) => {
    selectId.value = val.id;
    emit('submit', val);
    store.dispatch('setGroupId', val.id);
    if (node.level == 1) {
        node.expanded = true;
    }
    nextTick(() => {
        treeRef.value?.setCheckedKeys([val.id], true);
    });
};

const toggleGroupTab = async (type_: any, id: any) => {
    type.value = Number(type_);
    selectId.value = id;
    await getGroup();
};

/**
 * @description: 获取tree高度
 * @return {*}
 */
const getTreeH = () => {
    const h = treeH('.tree-scrollbar', props.gap);
    treeHeight.value = `${h}px`;
};

onMounted(() => {
    getTreeH();
    reSize(() => getTreeH());
});

watch(
    () => props.type,
    async val => {
        type.value = Number(val);
        await getGroup();
        selectId.value = 'all';
    },
    { immediate: true }
);
watch(
    () => props.groupId,
    async val => {
        selectId.value = val;
        await getGroup();
        // changeGroup({ id: val, type: '' })
    }
);
defineExpose({
    selectId,
    type,
    getGroup,
    changeGroup,
    toggleGroupTab,
    setCurrentSelectId: (data: any) => {
        selectId.value = data.id;
    },
    getTreeH
});
</script>

<style lang="scss" scoped>
.link-text {
    display: block;
}

.left-nav {
    width: 300px;
    box-sizing: border-box;

    // height: 600px;
    border: 1px solid #eaeaea;
    background-color: #fff;
    padding: 16px;
    margin-right: 16px;

    // box-shadow: 0px 0.5px 10px rgba(0, 0, 0, 0.2);
    .nav-title {
        display: flex;
        justify-content: space-between;
        margin-bottom: 10px;

        .plus-icon {
            cursor: pointer;
        }
    }

    .nav-text {
        font-size: 16px;
        font-weight: 600;
        color: #33302d;
    }

    .nav-input {
        width: 238px;
        padding: 16px 0 20px;
    }

    .el-tree-node__content {
        height: 35px !important;
    }

    .hover-text {
        width: 100%;
        display: flex;
        justify-content: space-between;
        align-items: center;
        line-height: 32px;

        .hover-detail {
            flex: 1;
            width: 0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            color: #535456;
            font-size: 14px;
        }

        .hover-detail-color {
            color: #ff6b00;
            flex: 1;
            width: 0;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .hover-detail:hover {
            color: #ff6b00;
        }

        .hover-icon {
            transform: rotate(90deg);
        }
    }

    .hide {
        // width: 176px;
    }

    .search-list {
        display: flex;
        flex-direction: column;

        .search-detail {
            margin: 0;
            color: #33302d;
        }

        .search-detail:hover {
            background-color: #f5f7fa;
        }

        .hover-text {
            line-height: 35px;
        }
    }

    .no-data {
        display: flex;
        flex-direction: column;
        align-items: center;

        .nodata-img {
            margin: 30px 0 30px 15px;
            width: 150px;
            height: 120px;
        }
    }

    .groups {
        color: #33302d;
        font-size: 14px;

        .search_group {
            margin: 20px 0;
        }

        :deep(.el-tree-node__expand-icon) {
            color: #ff6b00;
        }

        :deep(.el-tree-node__content) {
            padding-right: 8px;

            &:hover {
                background: #fffaf9;

                .icon-span {
                    .hover-icon {
                        visibility: visible;
                    }
                }

                .hover-detail {
                    color: #ff6b00;
                }
            }

            .icon-span {
                padding-right: 4px;
                display: flex;
                align-items: center;

                .hover-icon {
                    visibility: hidden;
                }
            }
        }

        :deep(.el-tree) {
            --el-tree-node-hover-bg-color: #fffaf9;
        }
    }

    :deep(.el-popper) {
        text-align: center !important;
    }
}

.select_grouping {
    width: 320px !important;
}

:deep(.formInput) {
    width: 340px;
}

:deep(.tree-hover) {
    background: #fffaf9;

    .hover-detail-color {
        color: #ff6b00 !important;
    }

    .hover-detail {
        color: #ff6b00 !important;
    }

    .icon-span {
        .hover-icon {
            visibility: visible !important;
        }
    }
}
</style>
